#include "UserApp.h"
#include "IR_Funcion.h"
#include "UART.h"   
#include "timer.h"
#include "LED.h"
#include "EEPROM.h"
#include "MotorDev.h"
#include "ADC.h"

uint8 TaskAction;
#if _OLD_ACTION_
const Typedef_ACTION  TABLE_ACTION[3] = {{0,2,12,1,0,1,0,1},{6,0,0,0,4,2,24,1},{6,2,6,1,0,2,12,1},};
#else
const Typedef_ACTION  TABLE_ACTION[] = {{LT_TM_DBC_ON, LT_ACT_ON, LT_TM_CHK_OFF, LT_TM_ACT_ON,  LT_ACT_ADJ, LT_TM_DBC_OFF, LT_TM_CHK_ON, LT_ACT_OFF, LT_TM_ACT_OFF1,LT_TM_ACT_OFF2},
                                        {PTDC_TM_DBC_ON, PTDC_ACT_ON, PTDC_TM_CHK_OFF, PTDC_TM_ACT_ON, PTDC_ACT_ADJ, PTDC_TM_DBC_OFF, PTDC_TM_CHK_ON, PTDC_ACT_OFF, PTDC_TM_ACT_OFF1,PTDC_TM_ACT_OFF2},
                                        {PTXC_TM_DBC_ON, PTXC_ACT_ON, PTXC_TM_CHK_OFF, PTXC_TM_ACT_ON, PTXC_ACT_ADJ, PTXC_TM_DBC_OFF, PTXC_TM_CHK_ON, PTXC_ACT_OFF, PTXC_TM_ACT_OFF1,PTXC_TM_ACT_OFF2},
                                        {LYQ_TM_DBC_ON, LYQ_ACT_ON, LYQ_TM_CHK_OFF, LYQ_TM_ACT_ON, LYQ_ACT_ADJ, LYQ_TM_DBC_OFF, LYQ_TM_CHK_ON, LYQ_ACT_OFF, LYQ_TM_ACT_OFF1,LYQ_TM_ACT_OFF2},
                                        {JNDC_TM_DBC_ON, JNDC_ACT_ON, JNDC_TM_CHK_OFF, JNDC_TM_ACT_ON, JNDC_ACT_ADJ, JNDC_TM_DBC_OFF, JNDC_TM_CHK_ON, JNDC_ACT_OFF, JNDC_TM_ACT_OFF1,JNDC_TM_ACT_OFF2},
                                        {JNXC_TM_DBC_ON, JNXC_ACT_ON, JNXC_TM_CHK_OFF, JNXC_TM_ACT_ON, JNXC_ACT_ADJ, JNXC_TM_DBC_OFF, JNXC_TM_CHK_ON, JNXC_ACT_OFF, JNXC_TM_ACT_OFF1,JNXC_TM_ACT_OFF2},
                                        {LDDC_TM_DBC_ON, LDDC_ACT_ON, LDDC_TM_CHK_OFF, LDDC_TM_ACT_ON, LDDC_ACT_ADJ, LDDC_TM_DBC_OFF, LDDC_TM_CHK_ON, LDDC_ACT_OFF, LDDC_TM_ACT_OFF1,LDDC_TM_ACT_OFF2},
                                        // {GYKG_TM_DBC_ON, GYKG_ACT_ON, GYKG_TM_CHK_OFF, GYKG_TM_ACT_ON, GYKG_ACT_ADJ, GYKG_TM_DBC_OFF, GYKG_TM_CHK_ON, GYKG_ACT_OFF, GYKG_TM_ACT_OFF1,GYKG_TM_ACT_OFF2},
};
#endif
Typedef_ACTION TblAction;

uint8 ActionSm;
// uint8 CntDbcActionOn;
// uint8 CntDbcActionOff;
uint8 CntDbcAction;
uint8 CntDlyTime;
uint8 CntIR_On,CntIR_Release;
int8 TmAdj;
bit F_LowPower;
// TYPEDEF_BIT FlagSave;
// #define F_VALVE_DIR FlagSave.b0

void    UpdateAction(void)
{
#if _OLD_ACTION_
    TblAction.TmDbcOn = TABLE_ACTION[TaskAction].TmDbcOn;
    TblAction.ActionOn = TABLE_ACTION[TaskAction].ActionOn;
    TblAction.TmDlyOn = TABLE_ACTION[TaskAction].TmDlyOn;
    TblAction.ActionDlyOn = TABLE_ACTION[TaskAction].ActionDlyOn;
    TblAction.TmDbcOff = TABLE_ACTION[TaskAction].TmDbcOff;
    TblAction.ActionOff = TABLE_ACTION[TaskAction].ActionOff;
    TblAction.TmDlyOff = TABLE_ACTION[TaskAction].TmDlyOff;
    TblAction.ActionDlyOff = TABLE_ACTION[TaskAction].ActionDlyOff;
#else
    if(TaskAction != TASK_GAN_YING_KAI_GUAN)
    {
        TblAction.TmDbcOn = TABLE_ACTION[TaskAction].TmDbcOn;
        TblAction.ActOn = TABLE_ACTION[TaskAction].ActOn;
        TblAction.TmChkOff = TABLE_ACTION[TaskAction].TmChkOff;
        TblAction.TmActOn = TABLE_ACTION[TaskAction].TmActOn;
        TblAction.TmAdjust = TABLE_ACTION[TaskAction].TmAdjust;
        TblAction.TmDbcOff = TABLE_ACTION[TaskAction].TmDbcOff;
        TblAction.TmChkOn = TABLE_ACTION[TaskAction].TmChkOn;
        TblAction.ActOff = TABLE_ACTION[TaskAction].ActOff;
        TblAction.TmActOff1 = TABLE_ACTION[TaskAction].TmActOff1;
        TblAction.TmActOff2 = TABLE_ACTION[TaskAction].TmActOff2;

        if(TblAction.TmAdjust)
        {
            if(TblAction.TmActOff1) TblAction.TmActOff1 += TmAdj;
            if(TblAction.TmActOff1 < 0)
                TblAction.TmActOff1 = 1;
            if(TblAction.TmActOff2) TblAction.TmActOff2 += TmAdj;
            if(TblAction.TmActOff2 < 0)
                TblAction.TmActOff2 = 1;


            // if(TblAction.TmActOn)   TblAction.TmActOn += TmAdj;
            // if(TmAdj & 0x80)
            // {
            // //---- 减时间 ----//
            //     if(TblAction.TmActOff1 > TmAdj)   TblAction.TmActOff1 -= TmAdj; 
            //     if(TblAction.TmActOff2 > TmAdj)   TblAction.TmActOff2 -= TmAdj; 
            // }
            // else
            // {
            // //---- 加时间 ----//
            //     if(TblAction.TmActOff1) TblAction.TmActOff1 += TmAdj;
            //     if(TblAction.TmActOff2) TblAction.TmActOff2 += TmAdj;
            // }
        }
    }
#endif
    // UART_SendByte(TblAction.TmDbcOn);
    // UART_SendByte(TblAction.ActionOn);
    // UART_SendByte(TblAction.TmDlyOn);
    // UART_SendByte(TblAction.ActionDlyOn);
    // UART_SendByte(TblAction.TmDbcOff);
    // UART_SendByte(TblAction.ActionOff);
    // UART_SendByte(TblAction.TmDlyOff);
    // UART_SendByte(TblAction.ActionDlyOff);
}

void    Action(uint8 action)
{
    switch(action)
    {
        case ACT_OFF:  
            CloseValve();
        break;

        case ACT_ON:
            OpenValve();
        break;

        case ACT_INVERT:
            if(F_STATE_VALVE)   
            {
                CloseValve();
            }
            else
            {
                OpenValve();
            }
        break;

        default:
        break;
    }

}


uint8 TmActOff;
bit F_IR_STATE ;
#if 1
void    Action_Proc(void)
{

    //-------- 感应开关单独处理 --------//
    if(TaskAction == TASK_GAN_YING_KAI_GUAN)
    {
        if(F_IR_Active)
        {
            if(F_IR_STATE == 0)
                Action(ACT_INVERT);
            F_IR_STATE = 1;
        }
        else
        {
            F_IR_STATE = 0;
        }

        if(F_STATE_VALVE)
        {
            CntDlyTime++;
            if(CntDlyTime >= GYKG_MAX_TIME_ON)
            {
                CntDlyTime = 0;
                Action(ACT_OFF);
            }
        }
        else
        {
            CntDlyTime = 0;
        }

        return;
    }

    //-------- 其它模式 --------//
    if(F_IR_Active)
    {
        // CntIR_Release = 0;
        if(CntIR_On < C_MAX_TM_IR_ON)
            CntIR_On++;
    }
    else
    {
        // CntIR_On = 0;
        if(CntIR_Release < C_MAX_TM_IR_RELEASE)
            CntIR_Release++;
    }


    switch(ActionSm)
    {
        //---- 感应检测+消抖 ----//
        case 0:
            if(F_IR_Active)
            {
                CntDbcAction++;
                if(CntDbcAction >= TblAction.TmDbcOn)
                {
                    CntDbcAction = 0;
                    ActionSm++;
                }
            }
            else
            {
                CntDbcAction = 0;
            }

            if(ActionSm == 0)
                break;

        //============================= 感应有效处理 ===============================//
        //---- 判断是否需要执行感应动作 ----//
        case 1:
            if(CntIR_Release >= TblAction.TmChkOff)
            {
                //---- 处理感应动作 ----//
                Action(TblAction.ActOn);   
                ActionSm++;
                CntDlyTime = 0;
            }                 
            else
            {
                ActionSm = 3;
            }
            CntIR_Release = 0;

            if(ActionSm == 1)
                break;

        //---- 等待感应动作时间 ----//
        case 2:
            if(TblAction.TmActOn == C_TM_INFINITE)
            {
                ActionSm++;
            }
            else
            {
                CntDlyTime++;
                if(CntDlyTime >= TblAction.TmActOn)
                {
                    Action(ACT_OFF);
                    CntDlyTime = 0;
                    ActionSm++;
                }

                if(F_IR_Active == NO)
                {
                    ActionSm = 3;
                }
            }

            if(ActionSm == 2)
                break;

        //============================= 感应释放处理 ===============================//
        //---- 等待感应释放 ----//
        case 3:
            if(F_IR_Active == NO)
            {
                CntDbcAction++;
                if(CntDbcAction >= TblAction.TmDbcOff)
                {
                    CntDbcAction = 0;
                    ActionSm++;
                }
            }
            else
            {
                CntDbcAction = 0;
            }

            if(ActionSm == 3)      
                break;

        //---- 感应释放 ----//
        case 4:
            if(CntIR_On < TblAction.TmChkOn)
            {
                //---- 处理感应动作 ----//
                TmActOff = (uint8)TblAction.TmActOff1; 
            }  
            else
            {
                TmActOff = (uint8)TblAction.TmActOff2; 
            }
            // UART_PrintfPara("",TmActOff);
            // UART_SendByte(TmActOff);
            Action(TblAction.ActOff);
            ActionSm++;
            CntDlyTime = 0;
            CntIR_On = 0;

            if(ActionSm == 4)      
                break;  

        //---- 
        case 5:
            CntDlyTime++;
            if(CntDlyTime >= TmActOff)
            {
                Action(ACT_OFF);
                CntDlyTime = 0;
                ActionSm = 0;
            }
            break;          

        //----

        default:
        break;
    }

}
#else

void    Action_Proc(void)
{

    //-------- 感应开关单独处理 --------//
    if(TaskAction == TASK_GAN_YING_KAI_GUAN)
    {
        if(F_IR_Active)
        {
            if(F_IR_STATE == 0)
                Action(ACT_INVERT);
            F_IR_STATE = 1;
        }
        else
        {
            F_IR_STATE = 0;
        }

        if(F_STATE_VALVE)
        {
            CntDlyTime++;
            if(CntDlyTime >= GYKG_MAX_TIME_ON)
            {
                CntDlyTime = 0;
                Action(ACT_OFF);
            }
        }
        else
        {
            CntDlyTime = 0;
        }

        return;
    }

    //-------- 其它模式 --------//
    if(F_IR_Active)
    {
        // CntIR_Release = 0;
        if(CntIR_On < C_MAX_TM_IR_ON)
            CntIR_On++;
    }
    else
    {
        // CntIR_On = 0;
        if(CntIR_Release < C_MAX_TM_IR_RELEASE)
            CntIR_Release++;
    }


    switch(ActionSm)
    {
        //---- 感应检测+消抖 ----//
        case 0:
            if(F_IR_Active)
            {
                CntDbcAction++;
                if(CntDbcAction >= TblAction.TmDbcOn)
                {
                    CntDbcAction = 0;
                    //============================= 感应有效处理 ===============================//
                    //---- 判断是否需要执行感应动作 ----//
                    // ActionSm++;
                    if(CntIR_Release >= TblAction.TmChkOff)
                    {
                        //---- 处理感应动作 ----//
                        Action(TblAction.ActOn);   
                        ActionSm++;
                        CntDlyTime = 0;
                    }                 
                    else
                    {
                        ActionSm = 2;
                    }
                    CntIR_Release = 0;

                }
            }
            else
            {
                CntDbcAction = 0;
            }

            if(ActionSm == 0)
                break;

        //---- 等待感应动作时间 ----//
        case 1:
            if(TblAction.TmActOn == C_TM_INFINITE)
            {
                ActionSm++;
            }
            else
            {
                CntDlyTime++;
                if(CntDlyTime >= TblAction.TmActOn)
                {
                    Action(ACT_OFF);
                    CntDlyTime = 0;
                    ActionSm++;
                }

                if(F_IR_Active == NO)
                {
                    ActionSm = 3;
                }
            }
            if(ActionSm == 1)
                break;

        //============================= 感应释放处理 ===============================//
        //---- 等待感应释放 ----//
        case 2:
            if(ActionSm == 2)
                break;

        case 3:
            if(F_IR_Active == NO)
            {
                CntDbcAction++;
                if(CntDbcAction >= TblAction.TmDbcOff)
                {
                    CntDbcAction = 0;
                    ActionSm++;
                }
            }
            else
            {
                CntDbcAction = 0;
            }

            if(ActionSm == 3)      
                break;

        //---- 感应释放 ----//
        case 4:
            if(CntIR_On < TblAction.TmChkOn)
            {
                //---- 处理感应动作 ----//
                TmActOff = (uint8)TblAction.TmActOff1; 
            }  
            else
            {
                TmActOff = (uint8)TblAction.TmActOff2; 
            }
            // UART_PrintfPara("",TmActOff);
            // UART_SendByte(TmActOff);
            Action(TblAction.ActOff);
            ActionSm++;
            CntDlyTime = 0;
            CntIR_On = 0;

            if(ActionSm == 4)      
                break;  

        //---- 
        case 5:
            CntDlyTime++;
            if(CntDlyTime >= TmActOff)
            {
                Action(ACT_OFF);
                CntDlyTime = 0;
                ActionSm = 0;
            }
            break;          

        //----

        default:
        break;
    }

}
#endif
void    ResetAction(void)
{
    CloseValve();
    ActionSm = 0;
    CntDbcAction = 0;
    CntIR_On = 0;
    CntIR_Release = C_MAX_TM_IR_RELEASE;    
    UpdateAction();
}


void    initUserApp(void)
{
    EEPROM_Read();
    IR_UpdateSensitivity();
    F_IR_STATE = NO;
    F_LowPower = NO;
    ResetAction();
}

const Typedef_MODE_INIT TAB_MODE_INIT[] = {
    {TASK_LONG_TOU,             C_NORMAL_DISTANCE,      C_DEFAULT_SENS_NORMAL},
    {TASK_DA_CHONG,             C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_XIAO_CHONG,           C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_LIN_YU_QI,            C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_JIE_NENG_DA_CHONG,    C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_JIE_NENG_XIAO_COHNG,  C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_LIANG_DUAN_DA_CHONG,  C_LONG_DISTANCE,        C_DEFAULT_SENS_LONG},
    {TASK_GAN_YING_KAI_GUAN,    C_NORMAL_DISTANCE,      C_DEFAULT_SENS_NORMAL},
};


void    DoCommand(void)
{
    if(IR_RemoteCmd == IR_CMD_LIANGDUANDACHONG)     IR_RemoteCmd = 7;
    if(IR_RemoteCmd == IR_CMD_GANYINGKAIGUAN)       IR_RemoteCmd = 8;

    if(IR_RemoteCmd < 9)
    {
        //-------- 命令码 < 9 --> 模式设置 --------//
        TaskAction = TAB_MODE_INIT[IR_RemoteCmd-1].TaskMode;
        IR_DistanceMode = TAB_MODE_INIT[IR_RemoteCmd-1].DistMode;
        IR_SensIdx = TAB_MODE_INIT[IR_RemoteCmd-1].SendIdx;
        ResetAction();
        
        // UpdateAction();
        IR_UpdateSensitivity();
        LED_Flash(2);   
        // LED_Flash(2,200,200);
        // LED_Flash_2();
    }
    else
    {
        //-------- 命令码 >= 9 --> 参数设置 --------//
        switch(IR_RemoteCmd)
        {
            //---- 颜色切换 ----//
            case IR_CMD_YANSEQIEHUAN:
                if(LedSel)  LedSel = 0;
                else        LedSel = 1;
            break;

            //---- 时间复位 ----//
            case IR_CMD_SHIJIANFUWEI:
                TmAdj = 0;
                UpdateAction();
                // LED_Flash(2,200,200);
                // LED_Flash_2();
                LED_Flash(2);
            break;

            //---- 发射功率 ----//
            case IR_CMD_FASHEGONGLV:
                if(IR_DistanceMode == C_NORMAL_DISTANCE)
                {
                    IR_DistanceMode = C_LONG_DISTANCE;
                    // IR_PowerSel = C_ISINK_82MA;
                    IR_SensIdx = C_MAX_IDX_SENS - 1;
                    LED_Flash(3);       
                    // LED_Flash(3,200,200);
                }
                else
                {
                    IR_DistanceMode = C_NORMAL_DISTANCE;
                    // IR_PowerSel = C_ISINK_16MA;
                    IR_SensIdx = 0;
                    LED_Flash(2);
                    // LED_Flash(2,200,200);
                    // LED_Flash_2();
                }
                // IR_UpdateSensitivity();  
            break;

            //---- 自动距离 ----//
            case IR_CMD_ZIDONGJULI:
                if(IR_StudyDistance())
                {
                    EEPROM_Write();
                    LED_Flash(1);
                    // LED_Flash(1,200,200);
                    return;
                }
            break;

            //---- 极性切换 ----//
            case IR_CMD_JIXINGQIEHUAN:
                if(F_VALVE_DIR) F_VALVE_DIR = 0;
                else            F_VALVE_DIR = 1;
                LED_Flash(2);   
                // LED_Flash(2,200,200);
                // LED_Flash_2();
            break;

            //---- 时间加 ----//
            case IR_CMD_SHIJIANJIA:
                if(TmAdj< C_MAX_TM_ADJ)     
                {
                    TmAdj++;
                    // EEPROM_Write();
                    UpdateAction();
                    LED_Flash(2);
                    //    LED_Flash(2,200,200);
                    // LED_Flash_2();
                }
            break;

            //---- 时间减 ----//
            case IR_CMD_SHIJIANJIAN:
                if(TmAdj >= C_MIN_TM_ADJ)   
                {
                    TmAdj--;
                    // EEPROM_Write();
                    UpdateAction();
                    LED_Flash(2);
                    // LED_Flash(2,200,200);
                    // LED_Flash_2();
                }
            break;

            //---- 距离+ ----//
            case IR_CMD_JULIJIA:
                IR_DistanceSetting(1);
                // EEPROM_Write();
                LED_Flash(2);
                // LED_Flash(2,200,200);
                // LED_Flash_2();
            break;

            //---- 距离- ----//
            case IR_CMD_JULIJIAN:

                IR_DistanceSetting(0);
                // EEPROM_Write();
                LED_Flash(2);
                // LED_Flash(2,200,200);
                // LED_Flash_2();
            break;

            //---- 未知 ----//
            default:
            break;
        }
    }
    EEPROM_Write();      

}

//-----------------------------------------------------------------------------
// Write EEPROM
//-----------------------------------------------------------------------------
void EEPROM_Write(void)
{
    PR_EEPROM_WR(EEP_ADDR_DISTANCE_MODE,IR_DistanceMode);
    PR_EEPROM_WR(EEP_ADDR_SENS_IDX,IR_SensIdx);
    PR_EEPROM_WR(EEP_ADDR_TASK_ACTION,TaskAction);
    PR_EEPROM_WR(EEP_ADDR_VLAVE_DIR,F_VALVE_DIR);
    PR_EEPROM_WR(EEP_ADDR_TM_ADJ,(uint8)TmAdj);
    PR_EEPROM_WR(EEP_ADDR_LED_SEL,LedSel);
    
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Read EEPROM
//-----------------------------------------------------------------------------
void EEPROM_Read(void)
{
    IR_DistanceMode = PR_EEPROM_RD(EEP_ADDR_DISTANCE_MODE);
    IR_SensIdx = PR_EEPROM_RD(EEP_ADDR_SENS_IDX);
    TaskAction = PR_EEPROM_RD(EEP_ADDR_TASK_ACTION);
    F_VALVE_DIR = PR_EEPROM_RD(EEP_ADDR_VLAVE_DIR);
    TmAdj = (int8)PR_EEPROM_RD(EEP_ADDR_TM_ADJ);
    LedSel = PR_EEPROM_RD(EEP_ADDR_LED_SEL);

    if((IR_DistanceMode >= 2) || (IR_SensIdx >= C_MAX_IDX_SENS) || (TaskAction >= 8) || (F_VALVE_DIR >= 2) || (LedSel>=2))
    {
        IR_DistanceMode = C_LONG_DISTANCE;
        IR_SensIdx = C_DEFAULT_SENS_LONG;
        TaskAction = C_DEFAULT_TASK_ACTION;
        F_VALVE_DIR = 0;
        TmAdj = 0;
        LedSel = 0;
    }
}


//-----------------------------------------------------------------------------
// Read EEPROM
//-----------------------------------------------------------------------------
uint16 AdBat;

void LowPowerCheck(void)
{
	initADC();

    _hvdoen = 1;
    // DelayXmSec(10*T1MS);
    GCC_DELAY(10);
    SelectADCChannel(ADC0_VDET);
    // SelectADCChannel(ADC0_VDET);
    AdBat = ADConverter();
    AdBat = ADConverter();
#ifdef _UART_EN_
    UART_SendByte(AdBat>>8);
    UART_SendByte(AdBat);
#endif
    if(AdBat < C_MIN_BAT_AD)
    {
        F_LowPower = YES;
    }
    
    if(AdBat >= C_MIN_BAT_RESUME)
    {
        F_LowPower = NO;
    }
    _hvdoen = 0;
    DeInitADC();
}
